package moltencore.network.protocol;

import spark.network.protocol.Base;
import spark.network.Util;
import spark.math.Vector2;

import java.nio.ByteBuffer;
import java.util.LinkedList;

/**
 * Contains information on which players (client id) are paired with which fields (field id)
 * playerFieldPairs[][] contains the actual pairs
 *
 * Example 1:
 * Simple all versus all game with 2 players
 * playerFieldPairs = { {0, 0}, {1, 1} }
 * ==>  playerFieldPairs tells us that the player with id 0 plays on field with id 0 etc.
 *
 * Example 2:
 * Team game where 1 player plays vs 2
 * playerFieldPairs = { {0, 0}, {1, 1}, {2, 1} }
 * ==>  playerFieldPairs tells us that the player with id 0 plays on field with id 0
 *                       and players with id 1 and 2 both play on field with id 1
 */
public class GameStartingNotification extends Base {
	public static final short TYPE = 0x45;
	private static final byte[] TYPE_BYTES = Util.makeBytes(TYPE);

	public static final int PLAYER_FIELD_PAIR_PLAYER_ID_INDEX = 0;
	public static final int PLAYER_FIELD_PAIR_FIELD_ID_INDEX = 1;

	private byte teamSize;
	private static final int TEAM_SIZE_LENGTH = Byte.SIZE / 8;

	// implied variable
	// private byte playerFieldPairsCount;
	private final static int PLAYER_FIELD_PAIRS_COUNT_LENGTH = Byte.SIZE / 8;
	private LinkedList<Long[]> playerFieldPairs = new LinkedList<Long[]>();

	private static final int SIZE =
			Base.SIZE +
			TEAM_SIZE_LENGTH +
	        PLAYER_FIELD_PAIRS_COUNT_LENGTH;

	public GameStartingNotification() {
		super(true, TYPE_BYTES);
	}

	public LinkedList<Long[]> getPlayerFieldPairs() {
		return playerFieldPairs;
	}

	public int getTeamSize() {
		return teamSize;
	}

	public void setTeamSize(int teamSize) {
		this.teamSize = (byte)teamSize;
	}

	@Override
	public void getBytes(byte[] buffer) {
		super.getBytes(buffer);
		ByteBuffer bb = ByteBuffer.wrap(buffer, Base.SIZE, buffer.length - Base.SIZE);
		bb.put(teamSize);
		bb.put((byte)playerFieldPairs.size());
		for(Long[] playerFieldPair : playerFieldPairs) {
			bb.putLong(playerFieldPair[PLAYER_FIELD_PAIR_PLAYER_ID_INDEX]);
			bb.putLong(playerFieldPair[PLAYER_FIELD_PAIR_FIELD_ID_INDEX]);
		}
	}

	@Override
	public void fill(byte[] buffer) {
		super.fill(buffer);
		ByteBuffer bb = ByteBuffer.wrap(buffer, Base.SIZE, buffer.length - Base.SIZE);
		teamSize = bb.get();
		int playerCount = bb.get();
		for(int i = 0; i < playerCount; i++) {
			playerFieldPairs.add(new Long[] {bb.getLong(), bb.getLong()});
		}
	}

	@Override
	public int getSize() {
		return SIZE + PLAYER_FIELD_PAIRS_COUNT_LENGTH * Long.SIZE * 2;
	}

	public static GameStartingNotification create(byte[] buffer, long receiveTime) {
		GameStartingNotification packet = new GameStartingNotification();
		packet.fill(buffer);
		return packet;
	}
}
